﻿using System;

namespace CommonFramework.Log
{
    public delegate void OnLogMessageDelegate(LogMessage msg, bool isBackTrace);
    /// <summary>
    /// 负责产出LogMessage 并且触发监听LogMessage产出的事件回调
    /// </summary>
    internal class LogMessageMaker : ILogger
    {
        /// <summary>
        /// 每条消息的最大长度
        /// </summary>
        public const int MaxMessageLength = 65536;
        /// <summary>
        /// 日志消息的处理回调
        /// </summary>
        public event OnLogMessageDelegate OnLogMessageCreated;
        /// <summary>
        /// 允许输出的日志级别
        /// </summary>
        public uint LogServerityFlagMask = 0xffff;

        #region 实现ILogger接口

        public void LogError(string msg)
        {
            MakeLogMessage(LogSeverity.Error,msg);
        }
        public void LogErrorFormat(string msg, params object[] formatArgs) 
            => LogError(string.Format(msg, formatArgs));

        public void LogWarning(string msg)
        {
            MakeLogMessage(LogSeverity.Warning, msg);
        }
        public void LogWarningFormat(string msg, params object[] formatArgs)
            => LogWarning(string.Format(msg, formatArgs));

        public void Log(string msg)
        {
            MakeLogMessage(LogSeverity.Info, msg);
        }
        public void LogFormat(string msg, params object[] formatArgs)
            => Log(string.Format(msg, formatArgs));

        public void LogVerbose(string msg)
        {
            MakeLogMessage(LogSeverity.Verbose, msg);
        }
        public void LogVerboseFormat(string msg, params object[] formatArgs)
            => LogVerbose(string.Format(msg, formatArgs));

        #endregion
        
        /// <summary>
        /// 产出一条日志消息
        /// </summary>
        public void MakeLogMessage(LogSeverity severity, string msg,object context=null)
        {
            if ((LogServerityFlagMask & (uint)severity) == 0)
                return;
            if (string.IsNullOrEmpty(msg))
                return;

            //过长的日志消息内容剔除
            if (msg.Length > MaxMessageLength)
                msg.Remove(MaxMessageLength);

            //日志消息对象
            LogMessageData rawMsg = new LogMessageData(msg, severity,context);
            var logMsg = new LogMessage(rawMsg);

            //触发回调处理
            if (OnLogMessageCreated != null)
            {
                var invocations = OnLogMessageCreated.GetInvocationList();
                //顺序方向
                for (int i = 0; i < invocations.Length; ++i)
                    invocations[i]?.DynamicInvoke(logMsg, false);
                //回溯方向
                for (int i = invocations.Length-1; i >=0 ; --i)
                    invocations[i]?.DynamicInvoke(logMsg, true);
            }
        }
    }
}